package com.astrob.tspant;

import java.util.ArrayList;


public class PublicFun {

    private static PublicFun instance = new PublicFun();

    public static PublicFun getInstance() {
        return instance;
    }

    public final double ALPHA = 1.0;//信息启发式因子，信息素的重要程度
    public final double BETA = 2.0;//期望启发式因子, 城市间距离的重要程度
    public final double ROU = 0.5;//信息素残留系数

    public int N_ANT_COUNT = 50;//蚂蚁数量
    public int N_IT_COUNT = 200;//迭代次数
    public int N_CITY_COUNT = 15;//城市数量

    public final double DBQ = 100.0;//总信息素
    public final double DB_MAX = Math.pow(10, 9);//一个标志数,用来初始化一个比较大的最优路径

    //两两城市间的信息量
    public double[][] Trial;

    //两两城市间的距离
    public double[][] Distance;

    //
    public ArrayList<PointE> cityList = new ArrayList<PointE>();//城市坐标；包括出发点；0为出发点
    public ArrayList<ABPath> ABPathList = new ArrayList<ABPath>();
    public PointE destCity = new PointE();//目的地城市坐标；可以是出发点；
    public final int INDEX_DEST = 10000;//_destCity加入到ABPath；i->indexDest

    //返回指定范围内的随机整数
    public int rnd(int nLow, int nUpper) {
        return (int) (Math.random() * (nUpper - nLow) + nLow);
    }

    //返回指定范围内的随机浮点数
    public double rnd(double dbLow, double dbUpper) {
        return Math.random() * (dbUpper - dbLow) + dbLow;
    }

    //可以是距离，也可以是时间
    public double getDistance(int i, int j) {
        double distance = 0;

        ABPath path = null;
        for (int k = 0; k < ABPathList.size(); k++) {
            ABPath s = ABPathList.get(k);
            if (s.isMatch(i, j)) {
                path = s;
                break;
            }
        }

        if (path != null) {
            return path.lenA2B;
        } else {
            //计算A->B最短路径；并保存最短路径
            if (cityList == null) {
                return 0;
            }
            int size = cityList.size();
            if (i < 0 && i >= size) {
                return 0;
            }
            if (j < 0 && j >= size) {
                return 0;
            }
            ABPath pathAB = calculatePath(cityList.get(i), cityList.get(j));
            if (pathAB != null) {
                pathAB.AIndex = i;
                pathAB.BIndex = j;
                ABPathList.add(pathAB);
                return pathAB.lenA2B;
            }

        }

        return distance;
    }

    //求最短路径
    public ABPath calculatePath(PointE A, PointE B) {
        if (A == null || B == null) {
            return null;
        }
        ABPath pathAB = new ABPath();

        pathAB.A = A;
        pathAB.B = B;
        pathAB.path.add(A);
        pathAB.path.add(B);
        double x = A.x - B.x;
        double y = A.y - B.y;
        pathAB.lenA2B = Math.sqrt(x * x + y * y);

        return pathAB;
    }

    public void crearABPath() {
        for (int i = 0; i < N_CITY_COUNT; i++) {
            for (int j = i; j < N_CITY_COUNT; j++) {
                if (i == j)
                    Distance[i][j] = 0.0;//同一个城市为0
                else {
                    double distance = getDistance(i, j);
                    Distance[i][j] = distance;
                    Distance[j][i] = Distance[i][j];
                }
            }

            if (destCity != null) {
                //各个城市到目的地的path
                ABPath pathAB = calculatePath(cityList.get(i), destCity);
                if (pathAB != null) {
                    pathAB.AIndex = i;
                    pathAB.BIndex = INDEX_DEST;
                    ABPathList.add(pathAB);
                }
            }
        }
    }

}